﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace WebCoreAPI.Controllers
{
    /// <summary>
    /// JWT的原理，实际开发时不使用，只是用来了解
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class JWTSimpleDemoController : ControllerBase
    {
        private readonly string _key = "sdfwerkwrjlk23#$@kljlkjlkj@@#%$^lkj";

        /// <summary>
        /// 生成JWT
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<String> CreateJWTDemo() {
            var claims = new List<Claim>();
            claims.Add(new Claim(ClaimTypes.NameIdentifier, "1"));
            claims.Add(new Claim(ClaimTypes.Name, "Feng"));
            claims.Add(new Claim(ClaimTypes.Role, "Admin"));
            claims.Add(new Claim(ClaimTypes.Country, "China"));
            claims.Add(new Claim(ClaimTypes.Email, "123@163.com"));
            claims.Add(new Claim(ClaimTypes.HomePhone, "12332345456"));
            claims.Add(new Claim("PassPort", "345456402"));
            DateTime expires = DateTime.Now.AddDays(1);
            byte[] secBytes= Encoding.UTF8.GetBytes(_key);
            var secKey= new SymmetricSecurityKey(secBytes);
            var credentials= new  SigningCredentials(secKey,SecurityAlgorithms.HmacSha256);
            var tokenDescriptor = new JwtSecurityToken(claims: claims,expires: expires, signingCredentials: credentials);
            string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
            return Ok(jwt);
        }

        /// <summary>
        /// 解析JWT,说明存放在Head和payload的内容是名文，
        /// </summary>
        /// <param name="jwt"></param>
        /// <returns>返回解析后的Head和Payload</returns>
        [HttpPost]

        public ActionResult<String> AnalyzeJTWDemo(String jwt)
        {
            string[] segments = jwt.Split('.');
            string head = JwtDecode(segments[0]);
            string payload = JwtDecode(segments[1]);
            return Ok($"head:{head},payload:{payload}");
        }

        /// <summary>
        /// 验证，并解析JWT
        /// </summary>
        /// <param name="jwt"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult<String> CheckAndAnalyzeJTWDemo(String jwt)
        {
            JwtSecurityTokenHandler tokenHandler = new();
            TokenValidationParameters valParam = new();
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
            valParam.IssuerSigningKey = securityKey;
            valParam.ValidateIssuer = false;
            valParam.ValidateAudience = false;
            ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,valParam, out SecurityToken secToken);

            StringBuilder stringBuilder = new StringBuilder("{");
            foreach (var claim in claimsPrincipal.Claims)
            {
                stringBuilder.Append($"{claim.Type}={claim.Value},");
            }
            stringBuilder.Remove(stringBuilder.Length - 1,1);
            stringBuilder.Append('}');
            return Ok(stringBuilder.ToString());
        }


        private string JwtDecode(string s)
        {
            s = s.Replace('-', '+').Replace('_', '/');
            switch (s.Length % 4)
            {
                case 2:
                    s += "==";
                    break;
                case 3:
                    s += "=";
                    break;
            }
            var bytes = Convert.FromBase64String(s);
            return Encoding.UTF8.GetString(bytes);
        }


    }
}
